using ChatBackend.Models;
using SqlSugar;

namespace ChatBackend.Repositories
{
    public class MessageRepository : IMessageRepository
    {
        private readonly ISqlSugarClient _db;

        public MessageRepository(ISqlSugarClient db)
        {
            _db = db;
        }

        public async Task<Message?> GetByIdAsync(int id)
        {
            return await _db.Queryable<Message>()
                .LeftJoin<User>((m, u) => m.SenderId == u.Id)
                .Where((m, u) => m.Id == id && !m.IsDeleted)
                .Select((m, u) => new Message
                {
                    Id = m.Id,
                    ChatRoomId = m.ChatRoomId,
                    SenderId = m.SenderId,
                    Content = m.Content,
                    Type = m.Type,
                    CreatedAt = m.CreatedAt,
                    IsEdited = m.IsEdited,
                    EditedAt = m.EditedAt,
                    IsDeleted = m.IsDeleted,
                    Sender = u
                })
                .FirstAsync();
        }

        public async Task<List<Message>> GetChatRoomMessagesAsync(int chatRoomId, int pageNumber = 1, int pageSize = 50)
        {
            var messages = await _db.Queryable<Message>()
                .Where(m => m.ChatRoomId == chatRoomId && !m.IsDeleted)
                .OrderByDescending(m => m.CreatedAt)
                .Skip((pageNumber - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();

            // 获取发送者信息
            foreach (var message in messages)
            {
                message.Sender = await _db.Queryable<User>()
                    .Where(u => u.Id == message.SenderId)
                    .FirstAsync();
            }

            return messages;
        }

        public async Task<Message?> GetLastMessageAsync(int chatRoomId)
        {
            var message = await _db.Queryable<Message>()
                .Where(m => m.ChatRoomId == chatRoomId && !m.IsDeleted)
                .OrderByDescending(m => m.CreatedAt)
                .FirstAsync();

            if (message != null)
            {
                message.Sender = await _db.Queryable<User>()
                    .Where(u => u.Id == message.SenderId)
                    .FirstAsync();
            }

            return message;
        }

        public async Task<int> GetUnreadCountAsync(int chatRoomId, int userId, DateTime? lastReadAt)
        {
            if (lastReadAt == null)
            {
                return await _db.Queryable<Message>()
                    .Where(m => m.ChatRoomId == chatRoomId && !m.IsDeleted && m.SenderId != userId)
                    .CountAsync();
            }

            return await _db.Queryable<Message>()
                .Where(m => m.ChatRoomId == chatRoomId && !m.IsDeleted &&
                           m.SenderId != userId && m.CreatedAt > lastReadAt)
                .CountAsync();
        }

        public async Task<Message> CreateAsync(Message message)
        {
            message.CreatedAt = DateTime.UtcNow;
            var result = await _db.Insertable(message).ExecuteReturnEntityAsync();
            return result;
        }

        public async Task<Message> UpdateAsync(Message message)
        {
            message.IsEdited = true;
            message.EditedAt = DateTime.UtcNow;
            await _db.Updateable(message).ExecuteCommandAsync();
            return message;
        }

        public async Task<bool> DeleteAsync(int id)
        {
            var result = await _db.Deleteable<Message>().Where(m => m.Id == id).ExecuteCommandAsync();
            return result > 0;
        }

        public async Task<bool> SoftDeleteAsync(int id)
        {
            var result = await _db.Updateable<Message>()
                .SetColumns(m => new Message { IsDeleted = true })
                .Where(m => m.Id == id)
                .ExecuteCommandAsync();
            return result > 0;
        }

        public async Task<bool> ExistsAsync(int id)
        {
            return await _db.Queryable<Message>()
                .Where(m => m.Id == id && !m.IsDeleted)
                .AnyAsync();
        }

        public async Task<int> GetTotalMessagesCountAsync(int chatRoomId)
        {
            return await _db.Queryable<Message>()
                .Where(m => m.ChatRoomId == chatRoomId && !m.IsDeleted)
                .CountAsync();
        }

        public async Task<List<Message>> SearchMessagesAsync(int chatRoomId, string searchTerm)
        {
            var messages = await _db.Queryable<Message>()
                .Where(m => m.ChatRoomId == chatRoomId && !m.IsDeleted && m.Content.Contains(searchTerm))
                .OrderByDescending(m => m.CreatedAt)
                .ToListAsync();

            // 获取发送者信息
            foreach (var message in messages)
            {
                message.Sender = await _db.Queryable<User>()
                    .Where(u => u.Id == message.SenderId)
                    .FirstAsync();
            }

            return messages;
        }
    }
}
